/**
 * 是否为邮箱
 * @param {*} s 需要判断的值
 * @returns
 */
export const isEmail = s => {
  return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(
    s
  );
};
/**
 * 是否为手机号
 * @param {*} s  需要判断的值
 * @returns
 */
export const isMobile = s => {
  return /^1[0-9]{10}$/.test(s);
};
/**
 * 是否为电话号码
 * @param {*} s  需要判断的值
 * @returns
 */
export const isPhone = s => {
  return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s);
};
/**
 * 是否为URL
 * @param {*} s 需要判断的值
 * @returns
 */
export const isURL = s => {
  return /^http[s]?:\/\/.*/.test(s);
};
/**
 * 是否为字符串
 * @param {*} o 需要判断的值
 * @returns
 */
export const isString = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'String';
};
/**
 * 是否为数字
 * @param {*} o 需要判断的值
 * @returns
 */
export const isNumber = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Number';
};
/**
 * 是否为Boolean
 * @param {*} o 需要判断的值
 * @returns
 */
export const isBoolean = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Boolean';
};
/**
 * 是否为函数
 * @param {*} o 需要判断的值
 * @returns
 */
export const isFunction = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Function';
};
/**
 * 是否为空
 * @param {*} o 需要判断的值
 * @returns
 */
export const isNull = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Null';
};
/**
 * 是否为undefined
 * @param {*} o 需要判断的值
 * @returns
 */
export const isUndefined = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Undefined';
};
/**
 * 是否对象
 * @param {*} o
 * @returns
 */
export const isObj = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Object';
};
/**
 * 是否数组
 * @param {*} o
 * @returns
 */
export const isArray = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Array';
};
/**
 * 是否时间
 * @param {*} o
 * @returns
 */
export const isDate = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Date';
};
/**
 * 是否正则
 * @param {*} o
 * @returns
 */
export const isRegExp = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'RegExp';
};
/**
 * 是否错误对象
 * @param {*} o
 * @returns
 */
export const isError = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Error';
};
/**
 * 是否Symbol函数
 * @param {*} o
 * @returns
 */
export const isSymbol = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Symbol';
};
/**
 * 是否Promise对象
 * @param {*} o
 * @returns
 */
export const isPromise = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Promise';
};
/**
 * 是否Set对象
 * @param {*} o
 * @returns
 */
export const isSet = o => {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Set';
};
/**
 * 是否是微信浏览器
 * @returns
 */
export const isWeiXin = () => {
  const ua = navigator.userAgent.toLowerCase();
  return ua.match(/microMessenger/i) == 'micromessenger';
};
/**
 * 是否是移动端
 * @returns
 */
export const isDeviceMobile = () => {
  return /android|webos|iphone|ipod|balckberry/i.test(ua);
};
/**
 * 是否是QQ浏览器
 * @returns
 */
export const isQQBrowser = () => {
  return !!ua.match(/mqqbrowser|qzone|qqbrowser|qbwebviewtype/i);
};
/**
 * 是否是爬虫
 * @returns
 */
export const isSpider = () => {
  return /adsbot|googlebot|bingbot|msnbot|yandexbot|baidubot|robot|careerbot|seznambot|bot|baiduspider|jikespider|symantecspider|scannerlwebcrawler|crawler|360spider|sosospider|sogou web sprider|sogou orion spider/.test(
    ua
  );
};
/**
 * 是否为PC端
 * @returns
 */
export const isPC = () => {
  var userAgentInfo = navigator.userAgent;
  var Agents = [
    'Android',
    'iPhone',
    'SymbianOS',
    'Windows Phone',
    'iPad',
    'iPod'
  ];
  var flag = true;
  for (var v = 0; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      flag = false;
      break;
    }
  }
  return flag;
};
/**
 * 去除html标签
 * @param {*} str
 * @returns
 */
export const removeHtmltag = str => {
  return str.replace(/<[^>]+>/g, '');
};
/**
 * 获取url参数
 * @param {*} name
 * @returns
 */
export const getQueryString_one = name => {
  const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  const search = window.location.search.split('?')[1] || '';
  const r = search.match(reg) || [];
  return r[2];
};
/**
 * 动态引入js
 * @param {*} src
 */
export const injectScript = src => {
  const s = document.createElement('script');
  s.type = 'text/javascript';
  s.async = true;
  s.src = src;
  const t = document.getElementsByTagName('script')[0];
  t.parentNode.insertBefore(s, t);
};
/**
 * 根据url地址下载
 * @param {*} url
 * @returns
 */
export const download = url => {
  var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
  var isSafari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;
  if (isChrome || isSafari) {
    var link = document.createElement('a');
    link.href = url;
    if (link.download !== undefined) {
      var fileName = url.substring(url.lastIndexOf('/') + 1, url.length);
      link.download = fileName;
    }
    if (document.createEvent) {
      var e = document.createEvent('MouseEvents');
      e.initEvent('click', true, true);
      link.dispatchEvent(e);
      return true;
    }
  }
  if (url.indexOf('?') === -1) {
    url += '?download';
  }
  window.open(url, '_self');
  return true;
};
/**
 * 获取滚动的坐标
 * @param {*} el
 * @returns
 */
export const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
/**
 * 滚动到顶部
 */
export const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
};
/**
 * el是否在视口范围内
 * @param {*} el
 * @param {*} partiallyVisible
 * @returns
 */
export const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
  const { top, left, bottom, right } = el.getBoundingClientRect();
  const { innerHeight, innerWidth } = window;
  return partiallyVisible
    ? ((top > 0 && top < innerHeight) ||
        (bottom > 0 && bottom < innerHeight)) &&
        ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
    : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};
/**
 * 劫持粘贴板
 * @param {*} value
 */
export const copyTextToClipboard = value => {
  var textArea = document.createElement('textarea');
  textArea.style.background = 'transparent';
  textArea.value = value;
  document.body.appendChild(textArea);
  textArea.select();
  try {
    var successful = document.execCommand('copy');
  } catch (err) {
    console.log('Oops, unable to copy');
  }
  document.body.removeChild(textArea);
};
/**
 * 判断类型集合
 * @param {*} str  需要判断的值
 * @param {*} type  需要判断的类型
 * @returns
 */
export const checkStr = (str, type) => {
  switch (type) {
    case 'phone': //手机号码
      return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
    case 'tel': //座机
      return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
    case 'card': //身份证
      return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
    case 'pwd': //密码以字母开头，长度在6~18之间，只能包含字母、数字和下划线
      return /^[a-zA-Z]\w{5,17}$/.test(str);
    case 'postal': //邮政编码
      return /[1-9]\d{5}(?!\d)/.test(str);
    case 'QQ': //QQ号
      return /^[1-9][0-9]{4,9}$/.test(str);
    case 'email': //邮箱
      return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
    case 'money': //金额(小数点2位)
      return /^\d*(?:\.\d{0,2})?$/.test(str);
    case 'URL': //网址
      return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(
        str
      );
    case 'IP': //IP
      return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(
        str
      );
    case 'date': //日期时间
      return (
        /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(
          str
        ) || /^(\d{4})\-(\d{2})\-(\d{2})$/.test(str)
      );
    case 'number': //数字
      return /^[0-9]$/.test(str);
    case 'english': //英文return /^[a-zA-Z]+$/.test(str);case 'chinese': //中文
      return /^[\\u4E00-\\u9FA5]+$/.test(str);
    case 'lower': //小写
      return /^[a-z]+$/.test(str);
    case 'upper': //大写
      return /^[A-Z]+$/.test(str);
    case 'HTML': //HTML标记
      return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
    default:
      return true;
  }
};
/**
 * 严格的身份证校验
 * @param {*} sId
 * @returns
 */
export const isCardID = sId => {
  if (!/(^\d{15}$)|(^\d{17}(\d|X|x)$)/.test(sId)) {
    console.log('你输入的身份证长度或格式错误');
    return false;
  } //身份证城市
  var aCity = {
    11: '北京',
    12: '天津',
    13: '河北',
    14: '山西',
    15: '内蒙古',
    21: '辽宁',
    22: '吉林',
    23: '黑龙江',
    31: '上海',
    32: '江苏',
    33: '浙江',
    34: '安徽',
    35: '福建',
    36: '江西',
    37: '山东',
    41: '河南',
    42: '湖北',
    43: '湖南',
    44: '广东',
    45: '广西',
    46: '海南',
    50: '重庆',
    51: '四川',
    52: '贵州',
    53: '云南',
    54: '西藏',
    61: '陕西',
    62: '甘肃',
    63: '青海',
    64: '宁夏',
    65: '新疆',
    71: '台湾',
    81: '香港',
    82: '澳门',
    91: '国外'
  };
  if (!aCity[parseInt(sId.substr(0, 2))]) {
    console.log('你的身份证地区非法');
    return false;
  } // 出生日期验证
  var sBirthday = (
      sId.substr(6, 4) +
      '-' +
      Number(sId.substr(10, 2)) +
      '-' +
      Number(sId.substr(12, 2))
    ).replace(/-/g, '/'),
    d = new Date(sBirthday);
  if (
    sBirthday !=
    d.getFullYear() + '/' + (d.getMonth() + 1) + '/' + d.getDate()
  ) {
    console.log('身份证上的出生日期非法');
    return false;
  } // 身份证号码校验
  var sum = 0,
    weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
    codes = '10X98765432';
  for (var i = 0; i < sId.length - 1; i++) {
    sum += sId[i] * weights[i];
  }
  var last = codes[sum % 11]; //计算出来的最后一位身份证号码
  if (sId[sId.length - 1] != last) {
    console.log('你输入的身份证号非法');
    return false;
  }
  return true;
};
/**
 * 随机数范围
 * @param {*} min
 * @param {*} max
 * @returns
 */
export const random = (min, max) => {
  if (arguments.length === 2) {
    return Math.floor(min + Math.random() * (max + 1 - min));
  } else {
    return null;
  }
};
/**
 * 将阿拉伯数字翻译成中文的大写数字
 * @param {*} num
 * @returns
 */
export const numberToChinese = num => {
  var AA = new Array(
    '零',
    '一',
    '二',
    '三',
    '四',
    '五',
    '六',
    '七',
    '八',
    '九',
    '十'
  );
  var BB = new Array('', '十', '百', '仟', '萬', '億', '点', '');
  var a = ('' + num).replace(/(^0*)/g, '').split('.'),
    k = 0,
    re = '';
  for (var i = a[0].length - 1; i >= 0; i--) {
    switch (k) {
      case 0:
        re = BB[7] + re;
        break;
      case 4:
        if (!new RegExp('0{4}//d{' + (a[0].length - i - 1) + '}$').test(a[0]))
          re = BB[4] + re;
        break;
      case 8:
        re = BB[5] + re;
        BB[7] = BB[5];
        k = 0;
        break;
    }
    if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0)
      re = AA[0] + re;
    if (a[0].charAt(i) != 0) re = AA[a[0].charAt(i)] + BB[k % 4] + re;
    k++;
  }
  if (a.length > 1) {
    // 加上小数部分(如果有小数部分)
    re += BB[6];
    for (var i = 0; i < a[1].length; i++) re += AA[a[1].charAt(i)];
  }
  if (re == '一十') re = '十';
  if (re.match(/^一/) && re.length == 3) re = re.replace('一', '');
  return re;
};
/**
 * 数组排序
 * @param {*} arr
 * @param {*} type 1：从小到大2：从大到小3：随机
 * @returns
 */
export const sort = (arr, type = 1) => {
  return arr.sort((a, b) => {
    switch (type) {
      case 1:
        return a - b;
      case 2:
        return b - a;
      case 3:
        return Math.random() - 0.5;
      default:
        return arr;
    }
  });
};
/**
 * 去重
 * @param {*} arr
 * @returns
 */
export const unique = arr => {
  if (Array.hasOwnProperty('from')) {
    return Array.from(new Set(arr));
  } else {
    var n = {},
      r = [];
    for (var i = 0; i < arr.length; i++) {
      if (!n[arr[i]]) {
        n[arr[i]] = true;
        r.push(arr[i]);
      }
    }
    return r;
  }
};
/**
 * 去除空格
 * @param {*} str
 * @param {*} type 1-所有空格2-前后空格3-前空格4-后空格
 * @returns
 */
export const trim = (str, type) => {
  type = type || 1;
  switch (type) {
    case 1:
      return str.replace(/\s+/g, '');
    case 2:
      return str.replace(/(^\s*)|(\s*$)/g, '');
    case 3:
      return str.replace(/(^\s*)/g, '');
    case 4:
      return str.replace(/(\s*$)/g, '');
    default:
      return str;
  }
};
/**
 * 检测密码强度
 * @param {*} str
 * @returns
 */
export const checkPwd_live = str => {
  var Lv = 0;
  if (str.length < 6) {
    return Lv;
  }
  if (/[0-9]/.test(str)) {
    Lv++;
  }
  if (/[a-z]/.test(str)) {
    Lv++;
  }
  if (/[A-Z]/.test(str)) {
    Lv++;
  }
  if (/[\.|-|_]/.test(str)) {
    Lv++;
  }
  return Lv;
};

export const debouncer = (fn, time, interval = 200) => {
  if (time - (window.debounceTimestamp || 0) > interval) {
    fn && fn();
    window.debounceTimestamp = time;
  }
};

export const isObjectEqual = (a, b) => {
  var aProps = Object.getOwnPropertyNames(a);
  var bProps = Object.getOwnPropertyNames(b);
  if (aProps.length !== bProps.length) {
    return false;
  }
  for (var i = 0; i < aProps.length; i++) {
    var propName = aProps[i];
    if (a[propName] !== b[propName]) {
      return false;
    }
  }
  return true;
};

export const required = val => {
  if (val === undefined || val === null || val === '') {
    throw new Error('该选项必填');
  }
  return !!val;
};

export const decimal = num => {
  return /^((([^0][0-9]+|0)\.([0-9]{1,2}))$)|^(([1-9]+)\.([0-9]{1,2})$)/.test(
    num
  );
};

export const integer = num => {
  return /^(([^0][0-9]+|0)$)|^(([1-9]+)$)/.test(num);
};

export const number = num => {
  return /^(([^0][0-9]+|0)\.([0-9]{1,2})$)|^(([^0][0-9]+|0)$)|^(([1-9]+)\.([0-9]{1,2})$)|^(([1-9]+)$)/.test(
    num
  );
};

export const RemoveChinese = strValue => {
  if (!strValue) return;
  return strValue.replace(/[\u4e00-\u9fa5]/g, '');
};
export const GetChinese = strValue => {
  if (strValue) return;
  return strValue.match(/[\u4e00-\u9fa5]/g).join('');
};

/**
 *
 * @param {*} str
 * @returns 1：密码弱 2：密码中等 3：密码强 4：密码很强
 */
export function checkPwd(str) {
  var nowLv = 0;
  if (str.length < 6) {
    return nowLv;
  }
  if (/[0-9]/.test(str)) {
    nowLv++;
  }
  if (/[a-z]/.test(str)) {
    nowLv++;
  }
  if (/[A-Z]/.test(str)) {
    nowLv++;
  }
  return nowLv;
}
/** 获取url参数字符串* 没有返回null*/
export function getQueryString(name) {
  let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  let r = window.location.search.substr(1).match(reg);
  if (r != null) {
    return unescape(r[2]);
  }
  return null;
}
/**
 * 校验是否为json
 * @param {*} str 
 * @returns 
 */
export function strIsJson(str){
   try {
      const jsonObj = JSON.parse(str);
      return true;
   } catch (error) {
      return false;
   }
}
